package com.mkb.controller;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageInfo;
import com.mkb.common.BaseController;
import com.mkb.common.ModuleURL;
import com.mkb.common.URL;
import com.mkb.conf.NotDuplicateRequest;
import com.mkb.entity.*;
import com.mkb.enums.GraphEnum;
import com.mkb.service.*;
import com.zz.common.result.ResultInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping(ModuleURL.GRAPH)
public class GraphController extends BaseController {
	@Autowired
    private GraphService graphService;
    @Autowired
    private GraphClueService graphClueService;
	@Autowired
    private AreaService areaService;
    @Autowired
    private GraphCaseService graphCaseService;
    @Autowired
    private GraphUserDetailService graphUserDetailService;
    @Autowired
    private UserDetailFamilyService userDetailFamilyService;
    @Autowired
    private GraphUserService graphUserService;

    @RequestMapping(value = URL.OP_LIST, method = RequestMethod.GET)
    public ModelAndView list(HttpServletRequest request) throws Exception{
        return new ModelAndView("page/graph/list");
    }
 
    @RequestMapping(value = URL.OP_LIST, method = RequestMethod.POST)
    public ModelAndView tableList(Model model, GraphDTO graphDTO) throws Exception{
        PageInfo<GraphDTO> response = graphService.queryPage(graphDTO);
        model.addAttribute("pageInfo", response);
        return new ModelAndView("page/graph/table_list");
    }

    @RequestMapping(value = URL.OP_DETAIL, method = RequestMethod.GET)
    public ModelAndView list(HttpServletRequest request, Long id) throws Exception{
        ModelAndView modelAndView = new ModelAndView("page/graph/detail");
        modelAndView.addObject("graphId", id);
        return modelAndView;
    }

    @RequestMapping(value = "/clueList", method = RequestMethod.POST)
    public ModelAndView clueList(HttpServletRequest request, GraphClueDTO graphClueDTO) throws Exception{
        ModelAndView modelAndView = new ModelAndView("page/graph/clue_list");
        PageInfo<GraphClueDTO> graphClueDTOPageInfo = graphClueService.queryPage(graphClueDTO);
        modelAndView.addObject("pageInfo", graphClueDTOPageInfo);
        return modelAndView;
    }

    @RequestMapping(value = "/clueUserList", method = RequestMethod.POST)
    public ModelAndView clueUserList(HttpServletRequest request, GraphUserDetailDTO graphUserDetailDTO) throws Exception{
        ModelAndView modelAndView;
        if (1 == graphUserDetailDTO.getOrigin()){
            modelAndView = new ModelAndView("page/graph/clue_use_list");
        } else {
            modelAndView = new ModelAndView("page/graph/case_use_list");
        }
        PageInfo<GraphUserDetailDTO> graphUserDetailDTOPageInfo = graphUserDetailService.queryPage(graphUserDetailDTO);
        modelAndView.addObject("pageInfo", graphUserDetailDTOPageInfo);
        return modelAndView;
    }

    @RequestMapping(value = "/caseList", method = RequestMethod.POST)
    public ModelAndView caseList(HttpServletRequest request, GraphCaseDTO graphCaseDTO) throws Exception{
        ModelAndView modelAndView = new ModelAndView("page/graph/case_list");
        PageInfo<GraphCaseDTO> graphCaseDTOPageInfo = graphCaseService.queryPage(graphCaseDTO);
        modelAndView.addObject("pageInfo", graphCaseDTOPageInfo);
        return modelAndView;
    }

    @RequestMapping(value = "/userFamilyList", method = RequestMethod.POST)
    public ModelAndView userFamilyList(HttpServletRequest request, UserDetailFamilyDTO userDetailFamilyDTO) throws Exception{
        ModelAndView modelAndView = new ModelAndView("page/graph/user_family_list");
        List<UserDetailFamilyDTO> userDetailFamilyDTOS = userDetailFamilyService.queryList(userDetailFamilyDTO);
        modelAndView.addObject("userFamilylist", userDetailFamilyDTOS);
        return modelAndView;
    }

    @RequestMapping(value = "/userList", method = RequestMethod.POST)
    public ModelAndView userList(HttpServletRequest request, GraphUserDTO graphUserDTO) throws Exception{
        ModelAndView modelAndView = new ModelAndView("page/graph/user_list");
        PageInfo<GraphUserDTO> graphUserDTOPageInfo = graphUserService.queryPage(graphUserDTO);
        modelAndView.addObject("pageInfo", graphUserDTOPageInfo);
        return modelAndView;
    }

    @RequestMapping(value = "/queryByParams", method = RequestMethod.POST)
    @ResponseBody
    public ResultInfo queryByParams(Model model, String name) throws Exception{
        if (StringUtils.isNotEmpty(name)){
            List<GraphDTO> response = graphService.queryList(GraphDTO.builder().name(name).build());
            return ResultInfo.ok(response);
        }
        return ResultInfo.ok();
    }

    @RequestMapping(value = URL.OP_CREATE, method = RequestMethod.GET)
    public ModelAndView createPage(Model model, String area) throws Exception{
        List<AreaDTO> areaDTOS = areaService.queryList(AreaDTO.builder().name(area).build());
        AreaDTO areaDTO = areaDTOS.get(0);
        model.addAttribute("longitude", String.valueOf(areaDTO.getLongitude()));
        model.addAttribute("dimension", String.valueOf(areaDTO.getDimension()));
        model.addAttribute("area", area);
        return new ModelAndView("page/graph/create");
    }
 
    @RequestMapping(value = URL.OP_CREATE, method = RequestMethod.POST)
    @ResponseBody
    @NotDuplicateRequest
    public ResultInfo createSave(HttpServletRequest request, @RequestBody GraphDTO graphDTO) throws Exception{
        UserInfoDTO userInfoDTO = getUserInfo(request);
        graphDTO.setCreateId(userInfoDTO.getId());
        graphDTO.setCreateTime(new Date());
        graphDTO.setCreator(userInfoDTO.getUsername());
        graphDTO.setName("");

        Long id = graphService.create(graphDTO);
        return  ResultInfo.ok(id);
    }
 
    @RequestMapping(value = URL.OP_DELETE, method = RequestMethod.GET)
    @ResponseBody
    public ResultInfo del(Long id) throws Exception{
        Boolean flag = graphService.deleteById(id);
        if (flag){
            return ResultInfo.ok();
        }else {
            return ResultInfo.err("该图层下面存在数据，不能删除");
        }
    }
 
    @RequestMapping(value = "/preview", method = RequestMethod.GET)
    public ModelAndView preview(HttpServletRequest request, Model model, String area) throws Exception{
        List<AreaDTO> areaDTOS = areaService.queryList(AreaDTO.builder().name(area).build());
        AreaDTO areaDTO = areaDTOS.get(0);
        model.addAttribute("longitude", String.valueOf(areaDTO.getLongitude()));
        model.addAttribute("dimension", String.valueOf(areaDTO.getDimension()));
        model.addAttribute("area", area);

        return new ModelAndView("page/graph/preview");
    }
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public ModelAndView search(Model model, Long graphId) throws Exception{
        GraphDTO graphDTO = graphService.getById(graphId);
        String areaJson = graphDTO.getAreaJson();

        if (graphDTO.getGraphType().equals(GraphEnum.POLYGON.getDesc())){
            double[] center = calculateCenter(areaJson);
            model.addAttribute("longitude", String.valueOf(center[0]));
            model.addAttribute("dimension", String.valueOf(center[1]));
        }else {
            JSONArray jsonArray = JSON.parseArray(areaJson);
            model.addAttribute("longitude", String.valueOf(jsonArray.get(1)));
            model.addAttribute("dimension", String.valueOf(jsonArray.get(0)));
        }

        model.addAttribute("area", graphDTO.getAreaName());

        return new ModelAndView("page/graph/preview");
    }

    public static double[] calculateCenter(String polygonString) {
        List<Double> xCoordinates = new ArrayList<>();
        List<Double> yCoordinates = new ArrayList<>();

        // 正则表达式匹配浮点数
        Pattern pattern = Pattern.compile("\\d+\\.\\d+");
        Matcher matcher = pattern.matcher(polygonString);

        while (matcher.find()) {
            String match = matcher.group();
            double coordinate = Double.parseDouble(match);
            if (xCoordinates.size() < yCoordinates.size()) {
                xCoordinates.add(coordinate);
            } else {
                yCoordinates.add(coordinate);
            }
        }

        // 计算平均x和y坐标
        double sumX = 0.0;
        double sumY = 0.0;
        for (double x : xCoordinates) {
            sumX += x;
        }
        for (double y : yCoordinates) {
            sumY += y;
        }
        double centerX = sumX / xCoordinates.size();
        double centerY = sumY / yCoordinates.size();

        return new double[]{centerX, centerY};
    }

    @RequestMapping(value = "/previewGraph", method = RequestMethod.POST)
    @ResponseBody
    public ResultInfo previewGraph(HttpServletRequest request) throws Exception{
        UserInfoDTO userInfoDTO = getUserInfo(request);
        //查询所有的图形
        List<GraphDTO> graphDTOS = graphService.queryFullList(GraphDTO.builder().build());

        //多边形
        List<GraphDTO> polygons = graphDTOS.stream().filter(item->item.getGraphType().equals(GraphEnum.POLYGON.getDesc())).collect(Collectors.toList());
        //圆
        List<GraphDTO> circles = graphDTOS.stream().filter(item->item.getGraphType().equals(GraphEnum.CIRCLE.getDesc())).collect(Collectors.toList());
        //文本
        List<GraphDTO> texts = graphDTOS.stream().filter(item->item.getGraphType().equals(GraphEnum.TEXT.getDesc())).collect(Collectors.toList());

        Map<String, Object> maps = new HashMap<>();
        maps.put("polygons", polygons);
        maps.put("circles", circles);
        maps.put("texts",texts);
        return ResultInfo.ok(maps);
    }


    @RequestMapping(value = URL.OP_MODIFY, method = RequestMethod.POST)
    @ResponseBody
    public ResultInfo modifySave(Model model, @RequestBody GraphDTO graphDTO) throws Exception{
        graphService.update(graphDTO);
        return  ResultInfo.ok();
    }
}
